Route Handler
https://nextjs.org/docs/app/building-your-application/routing/route-handlers
Route Segment の構成フォルダに route.ts ファイルを配置する
e.g.
code:app/api/hello/route.ts
export async function GET() {
return new NextResponse("Hello, Next.js!")
}
上記は /api/hello のリクエストを処理する
同じ階層に page.tsx も配置してしまうと、コンフリクトを起こしてエラーとなるので注意
export する関数は HTTP メソッドに対応する
サポートメソッド: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
code:tsx
export async function GET() {}
export async function POST() {}
リクエストされた HTTP メソッドが export されていない場合、405 Method Not Allowed を自動で返す
Route Handler は Web 標準の Fetch API に準拠する
関数が第 1 引数で受け取る NextRequest は Fetch API の Request に準拠する
https://nextjs.org/docs/app/api-reference/functions/next-response
https://developer.mozilla.org/ja/docs/Web/API/Request
関数が返す NextResponse は Fetch API の Response に準拠する
https://nextjs.org/docs/app/api-reference/functions/next-request
https://developer.mozilla.org/ja/docs/Web/API/Response
ステータスコードは、NextResponse.json() の第 2 引数にオプションで指定できる
code:ts
if (!session) {
return new NextResponse.json({ message: "Unauthorized" }, { status: 401 })
}
主な使用例: ブラウザからの HTTP リクエストに対応する
これにより、Cookie を元にしたログインユーザ情報の参照を Next.js 自身に委ねられる
結果、Component 側では単に Route Handler のエンドポイントを叩くだけで良い
code:tsx
"use client";
export function LikeButton({ photoId }: { photoId: string }) {
return (
<button
onClick={() => {
fetch(/api/photos/${photoId}/like, { method: "POST" });
}}
いいね
</button>
);
}
code:ts
export async function POST(
_: Request,
{ params }: { params: { photoId: string } }
) {
console.log(photoId: ${params.photoId} が「いいね」されました);
return Response.json({ liked: true });
}
Static Rendering と Dynamic Rendering のように、Static Route Handler と Dynamic Route Handler が存在する
Server Rendering Strategies
ビルド時にどちらか分かる
https://scrapbox.io/files/66c8389ccbaadf001ca63d8e.png
Static Route Handler
warning.icon Next 14 まではこちらがデフォルトだったが、15 から Dynamic Route Handler がデフォルトになった
= デフォルトでキャッシュが無効になった
https://nextjs.org/docs/app/building-your-application/upgrading/version-15#route-handlers
Route Handlers are not cached by default. You can, however, opt into caching for GET methods.
To do so, use a route config option such as export const dynamic = 'force-static' in your Route Handler file.
https://arc.net/l/quote/nxwqeolj
キャッシュを有効にするには、以下のように Route Segment Config を指定する必要がある
export const dynamic = 'force-static'
JSON ファイルをあらかじめキャッシュファイルとして出力する
リクエストのたびに外部 Web API サーバからデータを取得する必要がない
静的取得データ関数(e.g. fetch)を用いている場合、複数のリクエストに対して同じキャッシュファイルを利用する
HTTP メソッドは関係ないっぽい(GET だろうが POST だろうが Static になる) radish-miyazaki.icon
Next.js による fetch の拡張#66c54fee75d04f00000817f3
code:ts
export async function GET() {
const res = await fetch("https://...")
const data = await res.json()
// ...
}
Dynamic Route Handler
〜 Next 14
以下のいずれかが検出されると、Dynamic Route Handler と見なされる
1. Dynamic Segment を使用している場合
2. GET メソッドで Request を参照する
code:ts
export async function GET(request: NextRequest) {
const { searchParams } = new URL(request.url);
// ...
}
3. Dynamic Functions を使用する
code:ts
export async function GET() {
const cookieStore = cookies();
const token = cookieStore.get("token");
return new NextResponse("Hello, Next.js!", {
status: 200,
headers: { "Set-Cookie": token=${token?.value} },
});
}
4. GET 以外の HTTP メソッドを export する
code:ts
export async function POST() {
// ...
}
5. Route Segment Config の指定
dynamic 定数を "force-dynamic" に指定して export すると、対象の Route Segment とその配下のすべての Route Segment に Dynamic Rendering を強制できる
code:ts
export const dynamic = "force-dynamic";
日本語のほうだと記載があるんだけど、原文からは消えてる… radish-miyazaki.icon
https://ja.next-community-docs.dev/docs/app-router/building-your-application/routing/route-handlers#キャッシュのオプトアウト
一応切り替えて、Dynamic になることは確認済み: "next": "14.2.5"
Next 15 からこちらがデフォルトになったからっぽい
Next 15
こちらがデフォルト
Route Handler#66cc76db75d04f000040bc1f
#Next.js #App_Router